home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / WPrefs.app / MouseSettings.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-29  |  20.4 KB  |  830 lines

  1.  
  2. /* MouseSettings.c- mouse options (some are equivalent to xset)
  3.  * 
  4.  *  WPrefs - Window Maker Preferences Program
  5.  * 
  6.  *  Copyright (c) 1998 Alfredo K. Kojima
  7.  * 
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program; if not, write to the Free Software
  20.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  21.  *  USA.
  22.  */
  23.  
  24.  
  25. #include "WPrefs.h"
  26.  
  27. #include <X11/Xutil.h>
  28.  
  29. #include <math.h>
  30.  
  31. /* double-click tester */
  32. #include "double.h"
  33.  
  34.  
  35.  
  36. #define XSET    "xset"
  37.  
  38.  
  39.  
  40. typedef struct _Panel {
  41.     WMFrame *frame;
  42.  
  43.     char *sectionName;
  44.  
  45.     char *description;
  46.  
  47.     CallbackRec callbacks;
  48.     
  49.     WMWindow *win;
  50.     
  51.     WMFrame *speedF;
  52.     WMLabel *speedL;
  53.     WMSlider *speedS;
  54.     WMLabel *acceL;
  55.     WMTextField *acceT;
  56.     WMLabel *threL;
  57.     WMTextField *threT;
  58.     
  59.     WMFrame *ddelaF;
  60.     WMButton *ddelaB[5];
  61.     WMTextField *ddelaT;
  62.     WMLabel *ddelaL;
  63.     DoubleTest *tester;
  64.     
  65.     WMFrame *menuF;
  66.     WMLabel *listL;
  67.     WMLabel *appL;
  68.     WMLabel *selL;
  69.     WMPopUpButton *listP;
  70.     WMPopUpButton *appP;
  71.     WMPopUpButton *selP;
  72.  
  73.     WMButton *disaB;
  74.  
  75.     WMFrame *grabF;
  76.     WMPopUpButton *grabP;
  77.  
  78.     /**/
  79.     int maxThreshold;
  80.     float acceleration;
  81. } _Panel;
  82.  
  83.  
  84. #define ICON_FILE "mousesettings"
  85.  
  86. #define SPEED_ICON_FILE "mousespeed"
  87.  
  88. #define DELAY_ICON "timer%i"
  89. #define DELAY_ICON_S "timer%is"
  90.  
  91.  
  92. /* need access to the double click variables */
  93. #include "WINGsP.h"
  94.  
  95.  
  96.  
  97. static char *modifierNames[] = {
  98.     "Shift",
  99.     "Lock",
  100.     "Control",
  101.     "Mod1",
  102.     "Mod2",
  103.     "Mod3",
  104.     "Mod4",
  105.     "Mod5"
  106. };
  107.  
  108.  
  109. static char *buttonNames[] = {
  110.     "None",
  111.     "Btn1 (left)",
  112.     "Btn2 (middle)",
  113.     "Btn3 (right)",
  114.     "Btn4",
  115.     "Btn5"
  116. };
  117.  
  118.  
  119. #define DELAY(i)        ((i)*75+170)
  120.  
  121.  
  122. int ModifierFromKey(Display *dpy, char *key);
  123.  
  124.  
  125. static void
  126. setMouseAccel(WMScreen *scr, float accel, int threshold)
  127. {
  128.     int n, d;
  129.     
  130.     d = 10;
  131.     n = accel*d;
  132.  
  133.     XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
  134. }
  135.  
  136.  
  137. static void
  138. speedChange(WMWidget *w, void *data)
  139. {
  140.     _Panel *panel = (_Panel*)data;
  141.     int i;
  142.     char buffer[64];
  143.     int threshold;
  144.     char *tmp;
  145.  
  146.     if (w == NULL) {
  147.     float accel;
  148.  
  149.     tmp = WMGetTextFieldText(panel->acceT);
  150.     if (sscanf(tmp, "%f", &accel)!=1 || accel < 0) {
  151.         WMRunAlertPanel(WMWidgetScreen(panel->acceT), GetWindow(panel),
  152.                 _("Error"),
  153.                 _("Invalid mouse acceleration value. Must be a positive real value."),
  154.                 _("OK"), NULL, NULL);
  155.         free(tmp);
  156.         return;
  157.     }
  158.     panel->acceleration = accel;
  159.     free(tmp);
  160.     } else {
  161.     i = (int)WMGetSliderValue(panel->speedS);
  162.     
  163.     panel->acceleration = 0.25+(i*0.25);
  164.  
  165.     sprintf(buffer, "%.2f", 0.25+(i*0.25));
  166.     WMSetTextFieldText(panel->acceT, buffer);
  167.     }
  168.  
  169.     tmp = WMGetTextFieldText(panel->threT);
  170.     if (sscanf(tmp, "%i", &threshold)!=1 || threshold < 0 
  171.     || threshold > panel->maxThreshold) {
  172.     WMRunAlertPanel(WMWidgetScreen(panel->win), GetWindow(panel), _("Error"),
  173.             _("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
  174.             _("OK"), NULL, NULL);
  175.     } else {
  176.     setMouseAccel(WMWidgetScreen(panel->win), panel->acceleration, 
  177.               threshold);
  178.     }
  179.     free(tmp);
  180. }
  181.  
  182.  
  183. static void
  184. returnPressed(void *observerData, WMNotification *notification)
  185. {
  186.     _Panel *panel = (_Panel*)observerData;
  187.  
  188.     speedChange(NULL, panel);
  189. }
  190.  
  191.  
  192. static void
  193. doubleClick(WMWidget *w, void *data)
  194. {
  195.     _Panel *panel = (_Panel*)data;
  196.     int i;
  197.     extern _WINGsConfiguration WINGsConfiguration;
  198.     char buffer[32];
  199.  
  200.     for (i=0; i<5; i++) {
  201.     if (panel->ddelaB[i]==w)
  202.         break;
  203.     }
  204.     WINGsConfiguration.doubleClickDelay = DELAY(i);
  205.     
  206.     sprintf(buffer, "%i", DELAY(i));
  207.     WMSetTextFieldText(panel->ddelaT, buffer);
  208. }
  209.  
  210.  
  211.  
  212. int
  213. getbutton(char *str)
  214. {
  215.     if (!str)
  216.     return -2;
  217.  
  218.     if (strcasecmp(str, "none")==0)
  219.     return 0;
  220.     else if (strcasecmp(str, "left")==0)
  221.     return 1;
  222.     else if (strcasecmp(str, "middle")==0)
  223.     return 2;
  224.     else if (strcasecmp(str, "right")==0)
  225.     return 3;
  226.     else if (strcasecmp(str, "button1")==0)
  227.     return 1;
  228.     else if (strcasecmp(str, "button2")==0)
  229.     return 2;
  230.     else if (strcasecmp(str, "button3")==0)
  231.     return 3;
  232.     else if (strcasecmp(str, "button4")==0)
  233.     return 4;
  234.     else if (strcasecmp(str, "button5")==0) {
  235.     return 5;
  236.     } else {
  237.     return -1;
  238.     }
  239. }
  240.  
  241.  
  242. static void
  243. getMouseParameters(Display *dpy, float *accel, int *thre)
  244. {
  245.     int n, d;
  246.     
  247.     XGetPointerControl(dpy, &n, &d, thre);
  248.     
  249.     *accel = (float)n/(float)d;
  250. }
  251.  
  252.  
  253.  
  254. static void
  255. showData(_Panel *panel)
  256. {
  257.     char *str;
  258.     int i;
  259.     int a=-1, b=-1, c=-1;
  260.     float accel;
  261.     char buffer[32];
  262.     Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
  263.  
  264.     str = GetStringForKey("SelectWindowsMouseButton");
  265.     if (str) {
  266.     i = getbutton(str);
  267.     if (i==-1) {
  268.         a = 1;
  269.         wwarning(_("bad value %s for option %s"),str, "SelectWindowsMouseButton");
  270.     } else if (i>=0) {
  271.         a = i;
  272.     } 
  273.     } else {
  274.     a = 0;
  275.     }
  276.     WMSetPopUpButtonSelectedItem(panel->selP, a);
  277.     
  278.     str = GetStringForKey("WindowListMouseButton");
  279.     if (str) {
  280.     i = getbutton(str);
  281.     if (i==-1) {
  282.         b = 2;
  283.         wwarning(_("bad value %s for option %s"), str, "WindowListMouseButton");
  284.     } else if (i>=0) {
  285.         b = i;
  286.     } 
  287.     } else {
  288.     b = 0;
  289.     }
  290.     WMSetPopUpButtonSelectedItem(panel->listP, b);
  291.     
  292.     str = GetStringForKey("ApplicationMenuMouseButton");
  293.     if (str) {
  294.     i = getbutton(str);
  295.     if (i==-1) {
  296.         c = 3;
  297.         wwarning(_("bad value %s for option %s"), str, "ApplicationMenuMouseButton");
  298.     } else if (i>=0) {
  299.         c = i;
  300.     }
  301.     } else {
  302.     c = 0;
  303.     }
  304.     WMSetPopUpButtonSelectedItem(panel->appP, c);
  305.  
  306.     WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
  307.     
  308.     /**/
  309.     getMouseParameters(dpy, &accel, &a);
  310.     panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
  311.     if (a > panel->maxThreshold) {
  312.     panel->maxThreshold = a;
  313.     }
  314.     sprintf(buffer, "%i", a);
  315.     WMSetTextFieldText(panel->threT, buffer);
  316.  
  317.     WMSetSliderValue(panel->speedS, (accel - 0.25)/0.25);
  318.  
  319.     panel->acceleration = accel;
  320.     sprintf(buffer, "%.2f", accel);
  321.     WMSetTextFieldText(panel->acceT, buffer);
  322.  
  323.     /**/
  324.     b = GetIntegerForKey("DoubleClickTime");
  325.     /* find best match */
  326.     a = -1;
  327.     for (i=0; i<5; i++) {
  328.     if (DELAY(i) == b)
  329.         a = i;
  330.     }
  331.     if (a >= 0)
  332.     WMPerformButtonClick(panel->ddelaB[a]);
  333.     sprintf(buffer, "%i", b);
  334.     WMSetTextFieldText(panel->ddelaT, buffer);
  335.  
  336.     /**/
  337.     str = GetStringForKey("ModifierKey");
  338.     if (!str)
  339.     str = "mod1";
  340.     a = ModifierFromKey(dpy, str);
  341.  
  342.     if (a != -1) {
  343.     str = modifierNames[a];
  344.     
  345.     a = 0;
  346.     for (i=0; i<WMGetPopUpButtonNumberOfItems(panel->grabP); i++) {
  347.         if (strstr(WMGetPopUpButtonItem(panel->grabP, i), str)) {
  348.         WMSetPopUpButtonSelectedItem(panel->grabP, i);
  349.         a = 1;
  350.         break;
  351.         }
  352.     }
  353.     }
  354.  
  355.     if (a < 1) {
  356.     sscanf(WMGetPopUpButtonItem(panel->grabP, 0), "%s", buffer);
  357.     WMSetPopUpButtonSelectedItem(panel->grabP, 0);
  358.     wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
  359.          str, buffer);
  360.     }
  361. }
  362.  
  363.  
  364.  
  365. static void
  366. fillModifierPopUp(WMPopUpButton *pop)
  367. {
  368.     XModifierKeymap *mapping;
  369.     Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
  370.     int i, j;
  371.     char *str;
  372.     char buffer[64];
  373.  
  374.     
  375.     mapping = XGetModifierMapping(dpy);
  376.  
  377.     if (!mapping || mapping->max_keypermod==0) {
  378.     WMAddPopUpButtonItem(pop, "Mod1");
  379.     WMAddPopUpButtonItem(pop, "Mod2");
  380.     WMAddPopUpButtonItem(pop, "Mod3");
  381.     WMAddPopUpButtonItem(pop, "Mod4");
  382.     WMAddPopUpButtonItem(pop, "Mod5");
  383.     wwarning(_("could not retrieve keyboard modifier mapping"));
  384.     return;
  385.     }
  386.     
  387.     
  388.     for (j=0; j<8; j++) {
  389.     int idx;
  390.     char *array[8];
  391.     int a;
  392.     KeySym ksym;
  393.     int k;
  394.     char *ptr;
  395.     char *tmp;
  396.  
  397.     a = 0;
  398.     memset(array, 0, sizeof(char*)*8);
  399.     for (i=0; i < mapping->max_keypermod; i++) {
  400.         idx = i+j*mapping->max_keypermod;
  401.         if (mapping->modifiermap[idx]!=0) {
  402.         int l;
  403.         for (l=0; l<4; l++) {
  404.             ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
  405.             if (ksym!=NoSymbol)
  406.             break;
  407.         }
  408.         if (ksym!=NoSymbol)
  409.             str = XKeysymToString(ksym);
  410.         else
  411.             str = NULL;
  412.         if (str && !strstr(str, "_Lock") && !strstr(str, "Shift") 
  413.             && !strstr(str, "Control")) {
  414.             array[a++] = wstrdup(str);
  415.         }
  416.         }
  417.     }
  418.  
  419.     for (k=0; k<a; k++) {
  420.         if (array[k]==NULL)
  421.         continue;
  422.         tmp = wstrdup(array[k]);
  423.         ptr = strstr(tmp, "_L");
  424.         if (ptr)
  425.         *ptr = 0;
  426.         ptr = strstr(tmp, "_R");
  427.         if (ptr)
  428.         *ptr = 0;
  429.         sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
  430.         WMAddPopUpButtonItem(pop, buffer);
  431.         for (i=k+1; i<a; i++) {
  432.         if (array[i] == NULL)
  433.             continue;
  434.         if (strstr(array[i], tmp)) {
  435.             free(array[i]);
  436.             array[i]=NULL;
  437.             break;
  438.         }
  439.         }
  440.         free(tmp);
  441.     }
  442.     
  443.     while (--a>0) {
  444.         if (array[a])
  445.         free(array[a]);
  446.     }
  447.     }
  448.     
  449.     if (mapping)
  450.     XFreeModifiermap(mapping);
  451. }
  452.  
  453.  
  454.  
  455. static void
  456. createPanel(Panel *p)
  457. {
  458.     _Panel *panel = (_Panel*)p;
  459.     WMScreen *scr = WMWidgetScreen(panel->win);
  460.     WMPixmap *icon;
  461.     char *buf1, *buf2;
  462.     int i;
  463.     RColor color;
  464.     char *path;
  465.  
  466.     color.red = 0xaa;
  467.     color.green = 0xae;
  468.     color.blue = 0xaa;
  469.     
  470.     panel->frame = WMCreateFrame(panel->win);
  471.     WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
  472.     WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
  473.     
  474.     /**************** Mouse Speed ****************/
  475.     panel->speedF = WMCreateFrame(panel->frame);
  476.     WMResizeWidget(panel->speedF, 245, 100);
  477.     WMMoveWidget(panel->speedF, 15, 15);
  478.     WMSetFrameTitle(panel->speedF, _("Mouse Speed"));
  479.     
  480.     panel->speedL = WMCreateLabel(panel->speedF);
  481.     WMResizeWidget(panel->speedL, 40, 46);
  482.     WMMoveWidget(panel->speedL, 15, 14);
  483.     WMSetLabelImagePosition(panel->speedL, WIPImageOnly);
  484.     path = LocateImage(SPEED_ICON_FILE);
  485.     if (path) {
  486.     icon = WMCreateBlendedPixmapFromFile(scr, path, &color);
  487.     if (icon) {
  488.         WMSetLabelImage(panel->speedL, icon);    
  489.         WMReleasePixmap(icon);
  490.     } else {
  491.         wwarning(_("could not load icon %s"), path);
  492.     }
  493.     free(path);
  494.     }
  495.  
  496.     panel->speedS = WMCreateSlider(panel->speedF);
  497.     WMResizeWidget(panel->speedS, 160, 15);
  498.     WMMoveWidget(panel->speedS, 70, 35);
  499.     WMSetSliderMinValue(panel->speedS, 0);
  500.     WMSetSliderMaxValue(panel->speedS, 40);
  501.     WMSetSliderContinuous(panel->speedS, False);
  502.     WMSetSliderAction(panel->speedS, speedChange, panel);
  503.  
  504.     panel->acceL = WMCreateLabel(panel->speedF);
  505.     WMResizeWidget(panel->acceL, 70, 16);
  506.     WMMoveWidget(panel->acceL, 10, 67);
  507.     WMSetLabelTextAlignment(panel->acceL, WARight);
  508.     WMSetLabelText(panel->acceL, _("Acceler.:"));
  509.  
  510.     panel->acceT = WMCreateTextField(panel->speedF);
  511.     WMResizeWidget(panel->acceT, 40, 20);
  512.     WMMoveWidget(panel->acceT, 80, 65);
  513.     WMAddNotificationObserver(returnPressed, panel,
  514.                   WMTextDidEndEditingNotification, panel->acceT);
  515.  
  516.  
  517.     panel->threL = WMCreateLabel(panel->speedF);
  518.     WMResizeWidget(panel->threL, 80, 16);
  519.     WMMoveWidget(panel->threL, 120, 67);
  520.     WMSetLabelTextAlignment(panel->threL, WARight);
  521.     WMSetLabelText(panel->threL, _("Threshold:"));
  522.     
  523.     panel->threT = WMCreateTextField(panel->speedF);
  524.     WMResizeWidget(panel->threT, 30, 20);
  525.     WMMoveWidget(panel->threT, 200, 65);
  526.     WMAddNotificationObserver(returnPressed, panel,
  527.                   WMTextDidEndEditingNotification, panel->threT);
  528.  
  529.     WMMapSubwidgets(panel->speedF);
  530.     
  531.     /***************** Doubleclick Delay ****************/
  532.  
  533.     panel->ddelaF = WMCreateFrame(panel->frame);
  534.     WMResizeWidget(panel->ddelaF, 245, 95);
  535.     WMMoveWidget(panel->ddelaF, 15, 125);
  536.     WMSetFrameTitle(panel->ddelaF, _("Double-Click Delay"));
  537.     
  538.     buf1 = wmalloc(strlen(DELAY_ICON)+2);
  539.     buf2 = wmalloc(strlen(DELAY_ICON_S)+2);
  540.     
  541.     for (i = 0; i < 5; i++) {
  542.     panel->ddelaB[i] = WMCreateCustomButton(panel->ddelaF, 
  543.                         WBBStateChangeMask);
  544.     WMResizeWidget(panel->ddelaB[i], 25, 25);
  545.     WMMoveWidget(panel->ddelaB[i], 30+(40*i), 20);
  546.     WMSetButtonBordered(panel->ddelaB[i], False);
  547.     WMSetButtonImagePosition(panel->ddelaB[i], WIPImageOnly);
  548.     WMSetButtonAction(panel->ddelaB[i], doubleClick, panel);
  549.     if (i>0) {
  550.         WMGroupButtons(panel->ddelaB[0], panel->ddelaB[i]);
  551.     }
  552.     sprintf(buf1, DELAY_ICON, i+1);
  553.     sprintf(buf2, DELAY_ICON_S, i+1);
  554.     path = LocateImage(buf1);
  555.     if (path) {
  556.         icon = WMCreatePixmapFromFile(scr, path);
  557.         if (icon) {
  558.         WMSetButtonImage(panel->ddelaB[i], icon);
  559.         WMReleasePixmap(icon);
  560.         } else {
  561.         wwarning(_("could not load icon file %s"), path);
  562.         }
  563.         free(path);
  564.     }
  565.     path = LocateImage(buf2);
  566.     if (path) {
  567.         icon = WMCreatePixmapFromFile(scr, path);
  568.         if (icon) {
  569.         WMSetButtonAltImage(panel->ddelaB[i], icon);
  570.         WMReleasePixmap(icon);
  571.         } else {
  572.         wwarning(_("could not load icon file %s"), path);
  573.         }
  574.         free(path);
  575.     }
  576.     }
  577.     free(buf1);
  578.     free(buf2);
  579.  
  580.     panel->tester = CreateDoubleTest(panel->ddelaF, _("Test"));
  581.     WMResizeWidget(panel->tester, 84, 29);
  582.     WMMoveWidget(panel->tester, 35, 55);
  583.  
  584.     panel->ddelaT = WMCreateTextField(panel->ddelaF);
  585.     WMResizeWidget(panel->ddelaT, 40, 20);
  586.     WMMoveWidget(panel->ddelaT, 140, 60);
  587.  
  588.     panel->ddelaL = WMCreateLabel(panel->ddelaF);
  589.     WMResizeWidget(panel->ddelaL, 40, 16);
  590.     WMMoveWidget(panel->ddelaL, 185, 65);
  591.     {
  592.     WMFont *font;
  593.     WMColor *color;
  594.     
  595.     font = WMSystemFontOfSize(scr, 10);
  596.     color = WMDarkGrayColor(scr);
  597.     WMSetLabelTextColor(panel->ddelaL, color);
  598.     WMSetLabelFont(panel->ddelaL, font);
  599.     WMReleaseFont(font);
  600.     WMReleaseColor(color);
  601.     }
  602.     WMSetLabelText(panel->ddelaL, "msec");
  603.  
  604.     WMMapSubwidgets(panel->ddelaF);
  605.     
  606.     /* ************** Workspace Action Buttons **************** */
  607.     panel->menuF = WMCreateFrame(panel->frame);
  608.     WMResizeWidget(panel->menuF, 240, 145);
  609.     WMMoveWidget(panel->menuF, 270, 15);
  610.     WMSetFrameTitle(panel->menuF, _("Workspace Mouse Actions"));
  611.  
  612.     panel->disaB = WMCreateSwitchButton(panel->menuF);
  613.     WMResizeWidget(panel->disaB, 205, 18);
  614.     WMMoveWidget(panel->disaB, 10, 20);
  615.     WMSetButtonText(panel->disaB, _("Disable mouse actions"));
  616.  
  617.     
  618.     panel->appL = WMCreateLabel(panel->menuF);
  619.     WMResizeWidget(panel->appL, 125, 16);
  620.     WMMoveWidget(panel->appL, 5, 45);
  621.     WMSetLabelTextAlignment(panel->appL, WARight);
  622.     WMSetLabelText(panel->appL, _("Applications menu"));
  623.  
  624.     panel->appP = WMCreatePopUpButton(panel->menuF);
  625.     WMResizeWidget(panel->appP, 95, 20);
  626.     WMMoveWidget(panel->appP, 135, 45);
  627.     
  628.     panel->listL = WMCreateLabel(panel->menuF);
  629.     WMResizeWidget(panel->listL, 125, 16);
  630.     WMMoveWidget(panel->listL, 5, 80);
  631.     WMSetLabelTextAlignment(panel->listL, WARight);
  632.     WMSetLabelText(panel->listL, _("Window list menu"));
  633.     
  634.     panel->listP = WMCreatePopUpButton(panel->menuF);
  635.     WMResizeWidget(panel->listP, 95, 20);
  636.     WMMoveWidget(panel->listP, 135, 80);
  637.  
  638.     
  639.     panel->selL = WMCreateLabel(panel->menuF);
  640.     WMResizeWidget(panel->selL, 125, 16);
  641.     WMMoveWidget(panel->selL, 5, 115);
  642.     WMSetLabelTextAlignment(panel->selL, WARight);
  643.     WMSetLabelText(panel->selL, _("Select windows"));
  644.  
  645.     panel->selP = WMCreatePopUpButton(panel->menuF);
  646.     WMResizeWidget(panel->selP, 95, 20);
  647.     WMMoveWidget(panel->selP, 135, 115);
  648.  
  649.     for (i = 0; i < sizeof(buttonNames)/sizeof(char*); i++) {
  650.     WMAddPopUpButtonItem(panel->appP, buttonNames[i]);
  651.     WMAddPopUpButtonItem(panel->selP, buttonNames[i]);
  652.     WMAddPopUpButtonItem(panel->listP, buttonNames[i]);
  653.     }
  654.     
  655.     WMMapSubwidgets(panel->menuF);
  656.     
  657.     /* ************** Grab Modifier **************** */
  658.     panel->grabF = WMCreateFrame(panel->frame);
  659.     WMResizeWidget(panel->grabF, 240, 55);
  660.     WMMoveWidget(panel->grabF, 270, 165);
  661.     WMSetFrameTitle(panel->grabF, _("Mouse Grab Modifier"));
  662.  
  663.     WMSetBalloonTextForView(_("Keyboard modifier to use for actions that\n"
  664.                   "involve dragging windows with the mouse,\n"
  665.                   "clicking inside the window."),
  666.                 WMWidgetView(panel->grabF));
  667.  
  668.     panel->grabP = WMCreatePopUpButton(panel->grabF);
  669.     WMResizeWidget(panel->grabP, 160, 20);
  670.     WMMoveWidget(panel->grabP, 40, 25);
  671.  
  672.     fillModifierPopUp(panel->grabP);
  673.     
  674.     WMMapSubwidgets(panel->grabF);
  675.     
  676.     WMRealizeWidget(panel->frame);
  677.     WMMapSubwidgets(panel->frame);
  678.     
  679.     
  680.     showData(panel);
  681. }
  682.  
  683.  
  684. static void
  685. storeCommandInScript(char *cmd, char *line)
  686. {
  687.     char *path;
  688.     FILE *f;
  689.     char buffer[128];
  690.  
  691.     path = wstrappend(wusergnusteppath(), "/Library/WindowMaker/autostart");
  692.     
  693.     f = fopen(path, "r");
  694.     if (!f) {
  695.     f = fopen(path, "w");
  696.     if (!f) {
  697.         wsyserror(_("could not create %s"), path);
  698.         goto end;
  699.     }
  700.     fprintf(f, "#!/bin/sh\n");
  701.     fputs(line, f);
  702.     fputs("\n", f);
  703.     } else {
  704.     int len = strlen(cmd);
  705.     int ok = 0;
  706.     char *tmppath;
  707.     FILE *fo;
  708.  
  709.     tmppath = wstrappend(wusergnusteppath(), 
  710.                  "/Library/WindowMaker/autostart.tmp");
  711.     fo = fopen(tmppath, "w");
  712.     if (!fo) {
  713.         wsyserror(_("could not create temporary file %s"), tmppath);
  714.         goto end;
  715.     }
  716.  
  717.     while (!feof(f)) {
  718.         if (!fgets(buffer, 127, f)) {
  719.         break;
  720.             }
  721.             if (buffer[0] == '\n') {
  722.                 /* don't write empty lines, else the file will grow
  723.                  * indefinitely (one '\n' added at end of file on each save).
  724.                  */
  725.                 continue;
  726.             }
  727.         if (strncmp(buffer, cmd, len)==0) {
  728.         if (!ok) {
  729.             fputs(line, fo);
  730.             fputs("\n", fo);
  731.             ok = 1;
  732.         }
  733.         } else {
  734.         fputs(buffer, fo);
  735.         }        
  736.     }
  737.     if (!ok) {
  738.         fputs(line, fo);
  739.         fputs("\n", fo);
  740.     }
  741.     fclose(fo);
  742.  
  743.     if (rename(tmppath, path)!=0) {
  744.         wsyserror(_("could not rename file %s to %s\n"), tmppath, path);
  745.     }
  746.     free(tmppath);
  747.     }
  748.     sprintf(buffer, "chmod u+x %s", path);
  749.     system(buffer);
  750.  
  751. end:
  752.     free(path);
  753.     if (f)
  754.     fclose(f);
  755. }
  756.  
  757.  
  758. static void
  759. storeData(_Panel *panel)
  760. {
  761.     char buffer[64];
  762.     int i;
  763.     char *tmp, *p;
  764.     static char *button[6] = {"None", "left", "middle", "right", "Button4", "Button5"};
  765.     WMUserDefaults *udb = WMGetStandardUserDefaults();
  766.  
  767.     if (!WMGetUDBoolForKey(udb, "NoXSetStuff")) {
  768.     tmp = WMGetTextFieldText(panel->threT);
  769.     if (strlen(tmp)==0) {
  770.         free(tmp);
  771.         tmp = wstrdup("4");
  772.     }
  773.  
  774.     sprintf(buffer, XSET" m %i/%i %s\n", (int)(panel->acceleration*10),
  775.         10, tmp);
  776.     storeCommandInScript(XSET" m", buffer);
  777.  
  778.     free(tmp);
  779.     }
  780.  
  781.     tmp = WMGetTextFieldText(panel->ddelaT);
  782.     if (sscanf(tmp, "%i", &i) == 1 && i > 0)
  783.     SetIntegerForKey(i, "DoubleClickTime");
  784.  
  785.     SetBoolForKey(WMGetButtonSelected(panel->disaB), "DisableWSMouseActions");
  786.  
  787.     i = WMGetPopUpButtonSelectedItem(panel->appP);
  788.     SetStringForKey(button[i], "ApplicationMenuMouseButton");
  789.  
  790.     i = WMGetPopUpButtonSelectedItem(panel->listP);
  791.     SetStringForKey(button[i], "WindowListMouseButton");
  792.     
  793.     i = WMGetPopUpButtonSelectedItem(panel->selP);
  794.     SetStringForKey(button[i], "SelectWindowsMouseButton");
  795.     
  796.     tmp = WMGetPopUpButtonItem(panel->grabP,
  797.                    WMGetPopUpButtonSelectedItem(panel->grabP));
  798.     tmp = wstrdup(tmp);
  799.     p = strchr(tmp, ' ');
  800.     *p = 0;
  801.  
  802.     SetStringForKey(tmp, "ModifierKey");
  803.  
  804.     free(tmp);
  805. }
  806.  
  807.  
  808. Panel*
  809. InitMouseSettings(WMScreen *scr, WMWindow *win)
  810. {
  811.     _Panel *panel;
  812.     
  813.     panel = wmalloc(sizeof(_Panel));
  814.     memset(panel, 0, sizeof(_Panel));
  815.  
  816.     panel->sectionName = _("Mouse Preferences");
  817.  
  818.     panel->description = _("Mouse speed/acceleration, double click delay,\n"
  819.                "mouse button bindings etc.");
  820.  
  821.     panel->win = win;
  822.  
  823.     panel->callbacks.createWidgets = createPanel;
  824.     panel->callbacks.updateDomain = storeData;
  825.  
  826.     AddSection(panel, ICON_FILE);
  827.  
  828.     return panel;
  829. }
  830.